using System;
using System.Collections.Generic;
using System.Text;
using Stauffware.Common.Core;

namespace Stauffware.Common.Console
{
	/// <summary>
	/// Progress reporter that writes to the console.
	/// </summary>
	public class ConsoleProgressReporter : IProgressReporter
	{
		/// <see cref="Stauffware.Common.Core.IProgressReporter.ErrorCount"/> 
		public int ErrorCount
		{
			get { return this._errorCount; }
			set { this._errorCount = value; }
		}
		private int _errorCount = 0;

		/// <see cref="Stauffware.Common.Core.IProgressReporter.WarningCount"/> 
		public int WarningCount
		{
			get { return this._warningCount; }
			set { this._warningCount = value; }
		}
		private int _warningCount = 0;

		/// Suppresses all output except errors and warnings.
		public bool Terse = false;
	
		/// Specifies the maximum number of errors to report before exiting the program.
		public int MaxErrors = int.MaxValue;

		/// Specifies the exit code to return when the maximum number of errors has been reached.
		public int MaxErrorsExitCode = -1;

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogError"/> 
		public virtual void LogError (string descr)
		{
			this._errorCount++;
			System.Console.WriteLine("*** ERROR: " + descr);
			System.Console.WriteLine();
			if (this.ErrorCount >= this.MaxErrors)
#if SILVERLIGHT
				throw new QuitApplicationException();
#else
				Environment.Exit(this.MaxErrorsExitCode);
#endif
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogWarning"/> 
		public virtual void LogWarning (string descr)
		{
			this._warningCount++;
			System.Console.WriteLine("* WARNING: " + descr);
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogException(Exception)"/> 
		public virtual void LogException (Exception exc)
		{
			this.ErrorCount++;
			System.Console.Write("*** ");
			for (Exception x = exc; x != null; x = x.InnerException)
				System.Console.WriteLine(x.ToString());
			System.Console.WriteLine();
			if (this.ErrorCount >= this.MaxErrors)
#if SILVERLIGHT
				throw new QuitApplicationException();
#else
				Environment.Exit(this.MaxErrorsExitCode);
#endif
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogException(Exception, string)"/> 
		public virtual void LogException (Exception exc, string context)
		{
			this.ErrorCount++;
			System.Console.Write("*** " + context + " - ");
			for (Exception x = exc; x != null; x = x.InnerException)
				System.Console.WriteLine(x.ToString());
			System.Console.WriteLine();
			if (this.ErrorCount >= this.MaxErrors)
#if SILVERLIGHT
				throw new QuitApplicationException();
#else
				Environment.Exit(this.MaxErrorsExitCode);
#endif
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.LogException(Exception, string)"/> 
		public virtual void LogLine (string descr)
		{
			if (!this.Terse)
				System.Console.WriteLine(descr);
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.Log"/> 
		public virtual void Log (string text)
		{
			if (!this.Terse)
				System.Console.Write(text);
		}

		/// <see cref="Stauffware.Common.Core.IProgressReporter.Indent"/> 
		public virtual void Indent () { }
		
		/// <see cref="Stauffware.Common.Core.IProgressReporter.Outdent"/> 
		public virtual void Outdent () { }
	
		/// <see cref="Stauffware.Common.Core.IProgressReporter.OutdentAll"/> 
		public virtual void OutdentAll () { }

		/// <see cref="Stauffware.Common.Core.IProgressReporter.Clear"/> 
		public virtual void Clear () { }
	}
}